package com.isoft.c2team3service2.service;

import com.isoft.c2team3service2.entity.UserMessage;
import com.isoft.c2team3service2.entity.UserMessageStatus;
import com.isoft.c2team3service2.mapper.UserMessageMapper;
import com.isoft.c2team3service2.mapper.UserMessageStatusMapper;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * WebSocket服务类，处理实时消息通信
 */
@ServerEndpoint("/ws/message/{userId}")
@Component
public class WebSocketService {

    // 存储用户ID与WebSocket会话的映射
    private static final Map<Integer, Session> userSessionMap = new ConcurrentHashMap<>();

    // 由于Spring注入在WebSocket中特殊，使用静态变量和setter方法
    private static UserMessageMapper userMessageMapper;
    private static UserMessageStatusMapper userMessageStatusMapper;

    @Autowired
    public void setUserMessageMapper(UserMessageMapper mapper) {
        userMessageMapper = mapper;
    }

    @Autowired
    public void setUserMessageStatusMapper(UserMessageStatusMapper mapper) {
        userMessageStatusMapper = mapper;
    }

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") Integer userId) {
        userSessionMap.put(userId, session);
        System.out.println("用户[" + userId + "]已连接，当前在线人数：" + userSessionMap.size());
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(@PathParam("userId") Integer userId) {
        userSessionMap.remove(userId);
        System.out.println("用户[" + userId + "]已断开连接，当前在线人数：" + userSessionMap.size());
    }

    /**
     * 收到客户端消息后调用的方法
     */
    @OnMessage
    public void onMessage(String message, @PathParam("userId") Integer senderId) {
        try {
            // 解析消息格式，假设格式为"接收者ID|消息内容"
            String[] parts = message.split("\\|", 2);
            if (parts.length != 2) {
                sendMessageToUser(senderId, "消息格式错误，请使用'接收者ID|消息内容'格式");
                return;
            }

            Integer receiverId = Integer.parseInt(parts[0]);
            String content = parts[1];

            // 检查未回复消息数限制
            Integer unrepliedCount = userMessageMapper.countUnrepliedMessages(senderId, receiverId);
            if (unrepliedCount != null && unrepliedCount >= 5) { // 假设限制5条未回复消息
                sendMessageToUser(senderId, "对方未回复您的消息过多，请稍后再发");
                return;
            }

            // 保存消息到数据库
            UserMessage userMessage = new UserMessage();
            userMessage.setSenderId(senderId);
            userMessage.setReceiverId(receiverId);
            userMessage.setContent(content);
            userMessage.setCreateTime(LocalDateTime.now());
            userMessage.setStatus(0); // 0-未读
            userMessageMapper.insert(userMessage);

            // 保存消息状态
            UserMessageStatus status = new UserMessageStatus();
            status.setMessageId(userMessage.getId());
            status.setReceiverId(receiverId);
            status.setIsRead(0); // 0-未读
            userMessageStatusMapper.insert(status);

            // 向接收者发送消息
            String response = String.format("{\"type\":\"message\",\"senderId\":%d,\"content\":\"%s\",\"time\":\"%s\"}",
                    senderId, content, userMessage.getCreateTime());

            // 发送给接收者
            sendMessageToUser(receiverId, response);
            // 发送成功确认给发送者
            sendMessageToUser(senderId, String.format("{\"type\":\"success\",\"messageId\":%d}", userMessage.getId()));

        } catch (Exception e) {
            e.printStackTrace();
            sendMessageToUser(senderId, "消息发送失败：" + e.getMessage());
        }
    }

    /**
     * 发生错误时调用
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.err.println("WebSocket发生错误");
        error.printStackTrace();
    }

    /**
     * 发送消息给指定用户
     */
    public static void sendMessageToUser(Integer userId, String message) {
        Session session = userSessionMap.get(userId);
        if (session != null && session.isOpen()) {
            try {
                session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
